package com.chinapost.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.chinapost.dao.BaseDaoI;
import com.chinapost.po.Tdept;
import com.chinapost.po.Tuser;
import com.chinapost.service.DeptServiceI;
import com.chinapost.vo.DataGrid;
import com.chinapost.vo.Dept;
import com.chinapost.vo.Tree;

@Service("deptService")
public class DeptServiceImpl implements DeptServiceI {

	private BaseDaoI<Tdept> deptDao;
	private BaseDaoI<Tuser> userDao;
	
	

	public BaseDaoI<Tuser> getUserDao() {
		return userDao;
	}

	@Autowired
	public void setUserDao(BaseDaoI<Tuser> userDao) {
		this.userDao = userDao;
	}

	public BaseDaoI<Tdept> getDeptDao() {
		return deptDao;
	}

	@Autowired
	public void setDeptDao(BaseDaoI<Tdept> deptDao) {
		this.deptDao = deptDao;
	}


	@Override
	public DataGrid datagrid(Dept dept) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Dept> listDept() {
		List<Tdept> l;
		String hql = "from Tdept";
		l = deptDao.find(hql);
		return changeModel(l);
	}

	private List<Dept> changeModel(List<Tdept> l) {
		List<Dept> depts = new ArrayList<Dept>();
		if (l != null && l.size() > 0) {
			for (Tdept t : l) {
				Dept d = new Dept();
				BeanUtils.copyProperties(t, d);
				if(t.getTdept()!=null ){
					d.setPid(t.getTdept().getCid());
					d.setPdeptName(t.getTdept().getCname());
					if (t.getTdepts()!=null && t.getTdepts().size()>0){
						d.setState("closed");
					}else{
						d.setState("open");
					}
				}else{
					d.setState("open");
				}
				depts.add(d);
			}
		}
		return depts;
	}

	@Override
	public List<Tree> treeDept(String deptid) {
		if (deptid !=null && !deptid.trim().equals("")){
			List<Tdept> tdepts = new ArrayList<Tdept>();
			getTree(deptid,tdepts);
			Collections.sort(tdepts,new Comparator<Tdept>(){
				@Override
				public int compare(Tdept o1, Tdept o2) {
					if (o1.getCseq() == null) {
						o1.setCseq(1000);
					}
					if (o2.getCseq() == null) {
						o2.setCseq(1000);
					}
					return o1.getCseq().compareTo(o2.getCseq());
				}
			});
			return tree(tdepts);
			}
		return null;
	}

	private List<Tree> tree(List<Tdept> l) {
		List<Tree> depts = new ArrayList<Tree>();
		if (l != null && l.size() > 0) {
			for (Tdept t : l) {
				Tree tree = new Tree();
				tree.setId(t.getCid());
				tree.setText(t.getCname());
				if (t.getTdept()!=null){
					tree.setPid(t.getTdept().getCid());
					if (t.getTdepts()!=null && t.getTdepts().size()>0){
						tree.setState("closed");
					}else{
						tree.setState("open");
					}
				}else{
					tree.setState("open");
				}
				depts.add(tree);
			}
		}
		return depts;
	}
	

	@Override
	public void add(Dept dept) {
		Tdept t = new Tdept();
		Date d = new Date();
		BeanUtils.copyProperties(dept, t);
		t.setCid(UUID.randomUUID().toString());
		t.setCcreatedate(new Timestamp(d.getTime()));
		t.setCmodifydate(new Timestamp(d.getTime()));
		if (dept.getPid() != null) {
			t.setTdept(deptDao.get(Tdept.class, dept.getPid()));
		}
		deptDao.save(t);
	}

	@Override
	public void edit(Dept dept) {
		Tdept t = deptDao.get(Tdept.class, dept.getCid());
		Date d = new Date();
		BeanUtils.copyProperties(dept, t,new String[]{"ccreatedate","cmodifydate"});
		t.setCmodifydate(new Timestamp(d.getTime()));
		if (dept.getPid()!=null && !dept.getPid().equals(dept.getCid())){
			Tdept pt=deptDao.get(Tdept.class, dept.getPid());
			if (pt!=null){
				if (isDown(t,pt)){
					Set<Tdept> tdepts=t.getTdepts();
					if (tdepts!=null && tdepts.size()>0){
						for(Tdept tdept:tdepts){
							if (tdept!=null){
								tdept.setTdept(null);
							}
						}
					}
				}
				t.setTdept(pt);
			}
		}
	}

	private boolean isDown(Tdept t, Tdept pt) {
		if (pt.getTdept() != null) {
			if (pt.getTdept().getCid().equals(t.getCid())) {
				return true;
			} else {
				return isDown(t, pt.getTdept());
			}
		}
		return false;
	}

	@Override
	public void delete(Dept dept) {
		del(dept.getCid());
	}

	private void del(String cid) {
		Tdept t = deptDao.get(Tdept.class, cid);
		if (t != null) {
			Set<Tdept> depts = t.getTdepts();
			if (depts != null && !depts.isEmpty()) {
				for (Tdept tdept : depts) {
					del(tdept.getCid());
				}
			}
			deptDao.delete(t);
		}
	}

	@Override
	public List<Dept> treeGrid(String deptid) {
		if (deptid !=null && !deptid.trim().equals("")){
			List<Tdept> tdepts = new ArrayList<Tdept>();
			getTree(deptid,tdepts);
			Collections.sort(tdepts,new Comparator<Tdept>(){
				@Override
				public int compare(Tdept o1, Tdept o2) {
					if (o1.getCseq() == null) {
						o1.setCseq(1000);
					}
					if (o2.getCseq() == null) {
						o2.setCseq(1000);
					}
					return o1.getCseq().compareTo(o2.getCseq());
				}
			});
			return changeModel(tdepts);
			}
		return null;
	}
	
	private List<Tdept> getTree(String deptid,List<Tdept> depts){
		Tdept dept = deptDao.get(Tdept.class, deptid);
		depts.add(dept);
		Set<Tdept> tdepts = dept.getTdepts();
		List<Tdept> list = new ArrayList<Tdept>(tdepts);
		if (list!=null && list.size()>0){
			for (Tdept t : list){
				getTree(t.getCid(),depts);
			}
		}
		return depts;
	}

	@Override
	public List<String> getChildIds(String deptid) {
		List<Tdept> tdepts = new ArrayList<Tdept>();
		List<String> deptIds = new ArrayList<String>();
		getTree(deptid,tdepts);
		for (Tdept t : tdepts){
			deptIds.add(t.getCid());
		}
		return deptIds;
	}

}
